#include "SpriteSheet.h"

SpriteSheet::SpriteSheet() {}

// make sure safer release is called
SpriteSheet::~SpriteSheet() { release(); }

// safetly release all data
void SpriteSheet::release()
{
	m_rects.release();
}

// setup the texture and rects for the sprite sheet
// numColumns : number of columns in sheet
// numRows : number of rows in sheet
// count : total number of sprites in sheet ( can be less than rows * columns )
// spriteHeight : height in pixels of each sprites
// spriteWidth : width in pixels of each sprites
void SpriteSheet::initialize(LPCWSTR fileName, int count, int numRows, int numColumns, int spriteWidth, int spriteHeight, bool relativeToCamera)
{
	// setup basic sprite
	Texture::initialize(fileName,relativeToCamera);

	// set type to sprite sheet
	m_type = SHEET;

	// save rows and columns
	m_rows = numRows;
	m_columns = numColumns;

	// default draw sprite to 0
	m_index = 0;

	// generate rects for the sheet
	// temp rect used to hold the data
	RECT temp;
	temp.top = 0;
	temp.left = 0;
	temp.right = spriteWidth;
	temp.bottom = spriteHeight;

	// control variable to stop generating rects when all are done
	bool done = false;

	// generate the individual rects for each sprite
	for(int y = 0; y < m_rows && !done; ++y)
	{
		for(int x = 0; x < m_columns && !done; ++x)
		{
			// first make sure count hasn't been succeed
			if( (x+(m_columns*y)) >= count )
			{
				// all of the rects are finished exit the loops
				done = true;
				break;
			}

			// set up the rect
			temp.top = (y * spriteHeight);
			temp.bottom = (y + 1) * spriteHeight;
			temp.left = (x * spriteWidth);
			temp.right = (x + 1) * spriteWidth;
			
			// store in the rects list
			m_rects.add(temp);
		}
	}
}

// the rhe sprite to be drawn during render
// returns true if the sprite existed and was set successfully
// returns false otherwise
bool SpriteSheet::setCurrentSprite(int index)
{
	if( index >= 0 && index < m_rects.size() )
	{
		m_index = index;
		return true;
	}
	return false;
}

// draw the current sprite at the given position with the given scale and angle
void SpriteSheet::draw(V2DF pos, float rotAngle, float scale)
{
	int layer = 0;
	// make sure layer is less than 1 and greater than -1
	if(layer > 1)
		layer = 1;
	if(layer < 0)
		layer = 0;

	// get the sprite's rect
	RECT temp = m_rects.get(m_index);
	if(m_viewRect.top != -1)
	{
		// augment this rect by the view rect
		// only augment them if they are not equal
		if(temp.top != m_viewRect.top)
			temp.top -= m_viewRect.top;
		if(temp.left != m_viewRect.left)
			temp.left -= m_viewRect.left;
		if(temp.right != m_viewRect.right)
			temp.right -= m_viewRect.right;
		if(temp.bottom != m_viewRect.bottom)
			temp.bottom -= m_viewRect.bottom;
	}
	// draw the texture
	engine->renderTexture(textureID, pos, layer, scale, rotAngle, &temp, m_R, m_G, m_B, m_relativeToCamera);
}

// will be restricted to size of individual sprite
void SpriteSheet::setViewRect(RECT a_viewRect)
{
	// make sure that the rect is limited to the size of the image
	m_viewRect = a_viewRect;
	// restrict left
	if(m_viewRect.left < 0)
		m_viewRect.left = 0;
	if(m_viewRect.left > SpriteWidth())
		m_viewRect.left = SpriteWidth();
	// restrict right
	if(m_viewRect.right < 0)
		m_viewRect.right = 0;
	if(m_viewRect.right > SpriteWidth())
		m_viewRect.right = SpriteWidth();
	// restrict top
	if(m_viewRect.top < 0)
		m_viewRect.top = 0;
	if(m_viewRect.top > SpriteHeight())
		m_viewRect.top = SpriteHeight();
	// restrict bottom
	if(m_viewRect.bottom < 0)
		m_viewRect.bottom = 0;
	if(m_viewRect.bottom > SpriteHeight())
		m_viewRect.bottom = SpriteHeight();

	// now it will be re-made so that it represents the difference between a sprite-rect
	m_viewRect.top = m_rects.get(0).top - m_viewRect.top;
	m_viewRect.bottom = m_rects.get(0).bottom - m_viewRect.bottom;
	m_viewRect.left = m_rects.get(0).left - m_viewRect.left;
	m_viewRect.right = m_rects.get(0).right - m_viewRect.right;
}
